package com.xhh.nphm.framework.aspectj;

import com.xhh.nphm.api.controller.ForListPage;
import com.xhh.nphm.common.annotation.DataSource;
import com.xhh.nphm.common.constant.Constants;
import com.xhh.nphm.framework.datasource.DataBaseContextHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @description: 切面处理类
 * 当有注解时，按照指定的数据源进行操作
 * 没有注解时，按照默认的数据源进行操作
 * @Aspect 把当前类标识为一个切面供容器读取
 * @author: sun
 * @date: 2023-12-24 19:18
 * @version 1.0
 */
@Aspect
@Component
public class DynamicDataSourceAspect implements Ordered {

    static final Log logger = LogFactory.getLog(DynamicDataSourceAspect.class);

    /**
     * 指定切入点
     */
    @Pointcut("@within(com.xhh.nphm.common.annotation.DataSource)")
    public void dataSourcePointCut(){

    }

    @After("dataSourcePointCut()")
    public void after(){
        DataBaseContextHolder.chearDataSource();
    }
    /**
     * 环绕通知，包含了五种通知类型
     * @return
     */
    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point){
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        //默认数据源
        String defaultDataSource= Constants.GENERAL_DS;
        //获取该注解
        DataSource dataSource=method.getAnnotation(DataSource.class);
        //存在注解，直接切换该注解对应的数据源
        if(dataSource!=null){
            defaultDataSource = dataSource.value();
        }
        logger.info("use database：" + defaultDataSource + "----执 行----" + method.getName());
        //切换数据源
        DataBaseContextHolder.setDataBase(defaultDataSource);
        //继续执行方法
        Object result=null;
        try {
            result = point.proceed();
        } catch (Throwable throwable) {
            logger.error("use database："+ defaultDataSource, throwable);
            throwable.printStackTrace();
        } finally {
            //最后清除数据源
            DataBaseContextHolder.chearDataSource();
        }
        return result;
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
